<#include "/generation-templates/directive/contains.ftl"/>
<template>
  <div
    v-loading="loading"
    :element-loading-text="$t('view.loadingText')"
    class="app-container">
    <div ref="header">
      <el-card class="filter-container" shadow="never">
        <div class="condition-title"><el-icon name="search"></el-icon> {{ $t('view.conditionQuery') }}</div>
        <#list table.getFields() as field>
        <#if field.getRules().match("search")>
        <#if field.getRules().match("enum")>
        <el-select v-model="query.${field.getLowerCamelName()}" placeholder="${field.getComment()}" clearable class="filter-item">
          <el-option v-for="item in enumsData.${field.getLowerCamelName()}" :key="item.key" :label="item.value" :value="item.key"/>
        </el-select>
        <#else>
        <el-input v-model="query.${field.getLowerCamelName()}" clearable placeholder="${field.getComment()}" class="filter-item"/>
        </#if>
        </#if>
        </#list>
        <el-button v-waves class="filter-item" type="primary" icon="el-icon-search" @click="handleQuery">{{ $t('view.searchBtn') }}</el-button>
      </el-card>
      <el-card class="operation-bar" shadow="never">
        <el-button v-permission="'${table.getLowerCamelName()}.add${table.getCamelName()}'" v-waves class="filter-item" type="primary" icon="el-icon-plus" @click="handleAdd">{{ $t('view.addBtn') }}</el-button>
        <div class="fr">
          <export-type-radio v-model="exportOptions.exportCurrent"/>
          <book-type-option v-model="exportOptions.type"/>
          <el-button v-permission="'${table.getLowerCamelName()}.getExportedData'" v-waves class="filter-item" type="success" icon="el-icon-download" @click="handleExport">{{ $t('view.exportBtn') }}</el-button>
        </div>
      </el-card>
    </div>
    <!-- 数据表格 -->
    <el-table
      :data="data"
      :height="tableHeight"
      border
      fit
      highlight-current-row
      tooltip-effect="light"
      current-row-key="${primary.getLowerCamelName()}"
      row-key="${primary.getLowerCamelName()}"
      style="width: 100%;"
    >
      <#list table.getFields() as field>
      <#if field.getRules().match("table")>
      <#if field.getRules().match("enum")>
      <el-table-column show-overflow-tooltip label="${field.getComment()}" align="center" <#if field.getType().getSimpleName() == "LocalDateTime">width="160"<#elseif field.getLowerCamelName() == "operationUserName">width="100"<#else>min-width="${field.getComment()?length * 40}"</#if>>
        <template slot-scope="{ row }">
          <el-tag>{{ row.${field.getLowerCamelName()}.meaning }}</el-tag>
        </template>
      </el-table-column>
      <#elseif field.getType().getSimpleName() == "Boolean">
      <el-table-column show-overflow-tooltip label="${field.getComment()}" align="center" <#if field.getType().getSimpleName() == "LocalDateTime">width="160"<#elseif field.getLowerCamelName() == "operationUserName">width="100"<#else>min-width="${field.getComment()?length * 40}"</#if>>
        <template slot-scope="{ row }">
          <el-tag>{{ row.${field.getLowerCamelName()} ? $t('view.trueValue') : $t('view.falseValue') }}</el-tag>
        </template>
      </el-table-column>
      <#else>
      <el-table-column show-overflow-tooltip label="${field.getComment()}" align="center" <#if field.getType().getSimpleName() == "LocalDateTime">width="160"<#elseif field.getLowerCamelName() == "operationUserName">width="100"<#else>min-width="${field.getComment()?length * 40}"</#if>>
        <template slot-scope="{ row }">
          <span>{{ row.${field.getLowerCamelName()} }}</span>
        </template>
      </el-table-column>
      </#if>
      </#if>
      </#list>
      <el-table-column fixed="right" label="操作" align="center" width="240" class-name="small-padding fixed-width">
        <template slot-scope="{ row }">
          <el-button v-waves type="info" size="mini" @click="handleDetail(row)">{{ $t('view.detailBtn') }}</el-button>
          <el-button v-permission="'${table.getLowerCamelName()}.modify${table.getCamelName()}'" v-waves type="primary" size="mini" @click="handleModify(row)">{{ $t('view.modifyBtn') }}</el-button>
          <el-button v-permission="'${table.getLowerCamelName()}.delete${table.getCamelName()}'" v-waves type="danger" size="mini" @click="handleDelete(row)">{{ $t('view.deleteBtn') }}</el-button>
        </template>
      </el-table-column>
    </el-table>
    <!-- 分页 -->
    <div ref="pagination">
      <pagination :total="page.total" :page.sync="page.page" :limit.sync="page.size" @paginate="getData"/>
    </div>
    <!-- 更新表单dialog -->
    <el-dialog :title="dialogStatus === 'add' ? this.$t('view.addTitle') : this.$t('view.modifyTitle')" :visible.sync="dialogFormVisible" top="5vh">
      <el-form ref="dataForm" :rules="dataRules" :model="currentData" status-icon class="update-form" label-position="right" label-width="160px">
        <#list table.getFields() as field>
        <#if field.getRules().match('form')>
        <#if field.getRules().match('enum')>
        <el-form-item label="${field.getComment()}" prop="${field.getLowerCamelName()}">
          <el-radio-group v-model="currentData.${field.getLowerCamelName()}">
            <el-radio v-for="item of enumsData.${field.getLowerCamelName()}" :key="item.key" :label="item.key" border>{{ item.value }}</el-radio>
          </el-radio-group>
        </el-form-item>
        <#elseif field.getType().getSimpleName() == "Boolean">
        <el-form-item label="${field.getComment()}" prop="${field.getLowerCamelName()}">
          <el-radio-group v-model="currentData.${field.getLowerCamelName()}">
            <el-radio :label="true" border>{{ $t('view.trueValue') }}</el-radio>
            <el-radio :label="false" border>{{ $t('view.falseValue') }}</el-radio>
          </el-radio-group>
        </el-form-item>
        <#elseif field.getRules().match('img')>
        <el-form-item label="${field.getComment()}" prop="${field.getLowerCamelName()}">
          <el-input v-model="currentData.${field.getLowerCamelName()}" readonly prefix-icon="el-icon-picture" placeholder="请上传${field.getComment()}"/>
          <crop-upload :url="currentData.${field.getLowerCamelName()}" name="${field.getLowerCamelName()}" @upload-success="uploadSuccess"/>
        </el-form-item>
        <#else>
        <#if field.getSize() < 256>
        <el-form-item label="${field.getComment()}" prop="${field.getLowerCamelName()}">
          <el-input v-model="currentData.${field.getLowerCamelName()}" clearable placeholder="请输入${field.getComment()}"/>
        </el-form-item>
        <#else>
        <el-form-item label="${field.getComment()}" prop="${field.getLowerCamelName()}">
          <el-input :autosize="{ minRows: 4, maxRows: 8}" v-model="currentData.${field.getLowerCamelName()}" clearable type="textarea" placeholder="请输入${field.getComment()}"/>
        </el-form-item>
        </#if>
        </#if>
        </#if>
        </#list>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">{{ $t('view.formCancel') }}</el-button>
        <el-button :loading="updateLoading" type="primary" @click="dialogStatus === 'add'? addData() : modifyData()">{{ $t('view.formConfirm') }}</el-button>
      </div>
    </el-dialog>
    <!-- 详情dialog -->
    <el-dialog :visible.sync="dialogDetailVisible" :title="$t('view.detailTitle')" top="5vh">
      <el-form class="detail-form" label-position="right" label-width="160px">
        <#list table.getFields() as field>
        <#if !field.getRules().match("nod")>
        <el-form-item label="${field.getComment()}：">
          <#if field.getRules().match("enum")>
          <el-tag>{{ currentRow.${field.getLowerCamelName()}.meaning }}</el-tag>
          <#elseif field.getType().getSimpleName() == "Boolean">
          <el-tag>{{ currentRow.${field.getLowerCamelName()} ? $t('view.trueValue') : $t('view.falseValue') }}</el-tag>
          <#elseif field.getRules().match("img")>
          <span><img :src="currentRow.${field.getLowerCamelName()}.domain + currentRow.${field.getLowerCamelName()}.key" class="image-view"></span>
          <#else>
          <span>{{ currentRow.${field.getLowerCamelName()} }}</span>
          </#if>
        </el-form-item>
        </#if>
        </#list>
      </el-form>
    </el-dialog>
  </div>
</template>

<script>
import validationRules from '@/utils/validation-rules';
import Pagination from '@/components/Pagination'; // Secondary package based on el-pagination
<@contains tableInfo = table rules = "img">
import CropUpload from '@/components/CropUpload';
</@contains>
// options components
import BookTypeOption from '@/components/BookTypeOption';
import ExportTypeRadio from '@/components/ExportTypeRadio';
import { success } from '@/utils/message';
import { warningConfirm } from '@/utils/message-box';
import { BOOK_TYPE, CELL_AUTO_WIDTH, EXCEL_FILENAME } from '@/constant/system/system-constants';
import { extractData } from '@/utils/data';
import { get${table.getCamelName()}List, <@contains tableInfo = table rules = "enum">getEnums, </@contains>getExportedData, add${table.getCamelName()}, modify${table.getCamelName()}, delete${table.getCamelName()} } from '@/api/${apiBasePath}${table.getKebabName()}';

export default {
  name: '${table.getCamelName()}',
  components: { Pagination, <@contains tableInfo = table rules = "img">CropUpload, </@contains>BookTypeOption, ExportTypeRadio },
  data() {
    return {
      tableHeight: 0,
      data: [],
      <@contains tableInfo = table rules = "enum">
      enumsData: {},
      </@contains>
      loading: false,
      updateLoading: false,
      currentRow: { <#list table.getFields() as field><#if field.getRules().match("enum") || field.getRules().match("img")>${field.getLowerCamelName()}: {}, </#if></#list>},
      currentData: null,
      dialogFormVisible: false,
      dialogDetailVisible: false,
      dialogStatus: 'add',
      page: {
        page: 1,
        size: 20,
        total: 0,
        totalPages: 0
      },
      query: {
        <#list table.getFields() as field>
        <#if field.getRules().match("search")>
        <#if field.getType().getSimpleName() == "String">
        ${field.getLowerCamelName()}: '',
        <#elseif field.getType().getSimpleName() == "Boolean">
        ${field.getLowerCamelName()}: false,
        <#elseif field.getRules().match('enum')>
        ${field.getLowerCamelName()}: '',
        <#else>
        ${field.getLowerCamelName()}: undefined,
        </#if>
        </#if>
        </#list>
      },
      exportOptions: {
        type: BOOK_TYPE,
        exportCurrent: true,
        autoWidth: CELL_AUTO_WIDTH,
        filename: EXCEL_FILENAME
      },
      exportLoading: false
    };
  },
  computed: {
    dataRules() {
      return {
        <#list table.getFields() as field>
        <#if field.getRules().match('form')>
        ${field.getLowerCamelName()}: [
          <#if !field.isNullable()>
          validationRules.required('${field.getComment()}'),
          </#if>
          <#if field.getRules().match("email")>
          validationRules.email('${field.getComment()}'),
          </#if>
          <#-- 数字 -->
          <#if field.getRules().match("digits")>
          validationRules.digits('${field.getComment()}'),
          </#if>
          <#-- 字母 -->
          <#if field.getRules().match("alpha")>
          validationRules.alpha('${field.getComment()}'),
          </#if>
          <#-- 字母数字 -->
          <#if field.getRules().match("alphaNum")>
          validationRules.alphaNum('${field.getComment()}'),
          </#if>
          <#-- 字母数字下划线 -->
          <#if field.getRules().match("alphaNumDash")>
          validationRules.alphaNumDash('${field.getComment()}'),
          </#if>
          <#-- 汉字 -->
          <#if field.getRules().match("chinese")>
          validationRules.chinese('${field.getComment()}'),
          </#if>
          <#-- 身份证 -->
          <#if field.getRules().match("identity")>
          validationRules.identity('${field.getComment()}'),
          </#if>
          <#-- 路径 -->
          <#if field.getRules().match("path")>
          validationRules.path('${field.getComment()}'),
          </#if>
          <#-- 手机号码 -->
          <#if field.getRules().match("phone")>
          validationRules.phone('${field.getComment()}'),
          </#if>
          <#-- 邮政编码 -->
          <#if field.getRules().match("postcode")>
          validationRules.postcode('${field.getComment()}'),
          </#if>
          <#-- url -->
          <#if field.getRules().match("url")>
          validationRules.url('${field.getComment()}'),
          </#if>
          <#if field.getType().getSimpleName() == "String">
          <#if field.getRules().match("length")>
          <#if field.getRules().getRule("length").getParam("max")?? && field.getRules().getRule("length").getParam("min")?? && field.getRules().getRule("length").getParam("min") != field.getRules().getRule("length").getParam("max")>
          validationRules.lengthRange(field.getRules().getRule("length").getParam("min"), field.getRules().getRule("length").getParam("max"), '${field.getComment()}'),
          <#else>
          validationRules.length(${field.getRules().getRule("length").getParam("min")!field.getSize()}, '${field.getComment()}'),
          </#if>
          <#else>
          validationRules.maxLength(${field.getSize()}, '${field.getComment()}'),
          </#if>
          </#if>
          <#if field.getRules().match("enum")>
          validationRules.enum([<#list field.getRules().getRule("enum").getValues()?sort as value><#list value?split("-") as val><#if val?is_first>'${val}'</#if></#list><#if value?has_next>, </#if></#list>], '${field.getComment()}'),
          </#if>
        ],
        </#if>
        </#list>
      };
    }
  },
  created() {
    // 重置并获取数据
    this.resetCurrentData();
    this.getData();
    <@contains tableInfo = table rules = "enum">
    // 获取枚举数据
    getEnums().then(resp => {
      this.enumsData = resp.data;
    }).catch(() => {});
    </@contains>
  },
  mounted() {
    // 自动计算表格高度
    this.computeTableHeight();
  },
  methods: {
    computeTableHeight() {
      const dom = document.querySelector('.app-main');
      const viewHeight = dom.clientHeight;
      const headerHeight = this.$refs.header.clientHeight;
      const paginationHeight = this.$refs.pagination.clientHeight;
      this.$nextTick(() => {
        this.tableHeight = viewHeight - 15 * 2 - headerHeight - 15 - paginationHeight - 1;
      });
    },
    resetCurrentData() {
      this.currentData = Object.assign({}, {
        ${primary.getLowerCamelName()}: undefined,
        <#list table.getFields() as field>
        <#if field.getRules().match('form')>
        <#if field.getType().getSimpleName() == "String">
        ${field.getLowerCamelName()}: '',
        <#elseif field.getType().getSimpleName() == "Boolean">
        ${field.getLowerCamelName()}: false,
        <#elseif field.getRules().match('enum')>
        ${field.getLowerCamelName()}: 'a',
        <#else>
        ${field.getLowerCamelName()}: undefined,
        </#if>
        </#if>
        </#list>
      });
    },
    getData(page, query = {}) {
      this.loading = true;
      if (!page) {
        page = this.page;
      }
      get${table.getCamelName()}List(page, query).then(resp => {
        const data = resp.data;
        this.data = data.content;
        this.page.page = data.number + 1;
        this.page.total = data.totalElements;
        this.page.totalPages = data.totalPages;
        this.loading = false;
      }).catch(resp => {
        this.loading = false;
      });
    },
    handleQuery() {
      const page = Object.assign({}, this.page);
      page.page = 1;
      this.getData(page, this.query);
    },
    handleDetail(row) {
      this.currentRow = row;
      this.dialogDetailVisible = true;
    },
    handleAdd() {
      this.resetCurrentData();
      this.dialogStatus = 'add';
      this.dialogFormVisible = true;
      this.$nextTick(() => {
        this.$refs['dataForm'].clearValidate();
      });
    },
    addData() {
      this.$refs['dataForm'].validate((valid) => {
        if (valid) {
          this.updateLoading = true;
          add${table.getCamelName()}(this.currentData).then(resp => {
            this.getData(this.page, this.query);
            this.updateLoading = false;
            this.dialogFormVisible = false;
            success(resp.message);
          }).catch(resp => {
            this.updateLoading = false;
          });
        }
      });
    },
    handleModify(row) {
      const data = Object.assign({}, row); // copy obj
      <#list table.getFields() as field>
      <#if field.getRules().match('enum')>
      data.${field.getLowerCamelName()} = data.${field.getLowerCamelName()}.value;
      <#elseif field.getRules().match('img')>
      data.${field.getLowerCamelName()} = data.${field.getLowerCamelName()}.key;
      </#if>
      </#list>
      this.currentData = data;
      this.dialogStatus = 'modify';
      this.dialogFormVisible = true;
      this.$nextTick(() => {
        this.$refs['dataForm'].clearValidate();
      });
    },
    modifyData() {
      this.$refs['dataForm'].validate(valid => {
        if (valid) {
          this.updateLoading = true;
          modify${table.getCamelName()}(this.currentData).then(resp => {
            this.getData(this.page, this.query);
            this.updateLoading = false;
            this.dialogFormVisible = false;
            success(resp.message);
          }).catch(resp => {
            this.updateLoading = false;
          });
        }
      });
    },
    handleDelete(row) {
      warningConfirm(this.$t('view.deleteTip'), done => {
        this.deleteData(row.${primary.getLowerCamelName()}, done);
      });
    },
    deleteData(id, done) {
      delete${table.getCamelName()}({ id }).then(resp => {
        this.getData(this.page, this.query);
        success(resp.message);
        done();
      }).catch(resp => {
        done();
      });
    },
    handleExport() {
      this.exportLoading = true;
      import('@/vendor/Export2Excel').then(excel => {
        if (!this.exportOptions.exportCurrent) {
          // 导出全部数据
          getExportedData(this.query).then(resp => {
            excel.export_json_to_excel({
              header: resp.data.headers,
              data: resp.data.data,
              filename: this.exportOptions.filename,
              autoWidth: this.exportOptions.autoWidth,
              bookType: this.exportOptions.type
            });
            this.exportLoading = false;
          }).catch(() => {
            this.exportLoading = false;
          });
          return;
        }
        // 导出本页数据
        const headers = [<#list table.getFields() as field><#if field.getRules().match("excel")>'${field.getComment()}', </#if></#list>];
        const titles = [<#list table.getFields() as field><#if field.getRules().match("excel")><#if field.getRules().match("enum")>'${field.getLowerCamelName()}.meaning', <#elseif field.getRules().match("img")>'${field.getLowerCamelName()}.key', <#else>'${field.getLowerCamelName()}', </#if></#if></#list>];
        const data = extractData(titles, this.data);
        excel.export_json_to_excel({
          header: headers,
          data,
          filename: this.exportOptions.filename,
          autoWidth: this.exportOptions.autoWidth,
          bookType: this.exportOptions.type
        });
        this.exportLoading = false;
      }).catch(() => {
        this.exportLoading = false;
      });
    },
    <@contains tableInfo = table rules = "img">
    uploadSuccess(resp) {
      this.currentData[resp.name] = resp.data.key;
      this.$refs['dataForm'].validateField(resp.name);
    }
    </@contains>
  }
};
</script>
